<template>
<div>
  <div class="progress" v-if="showProgress">
    <vs-progressbar :now="progress" type="primary" striped animated></vs-progressbar>
  </div> 
  <form method="post">
    <div class="form-group">
      <div class="input-group"> 
        <input type="text" class="form-control" v-model="fileName" readonly>
        <span class="input-group-btn">
          <span class="btn btn-primary btn-file">
            {{ $t("common.browse") }}&hellip;
            <input type="file" v-el:container @change.prevent="onChange" :accept="accept">
          </span>
        </span>
      </div>
    </div>
    <button type="button" class="btn btn-default" :attr="{disabled: state != ''}" @click.prevent="onSubmit">{{ $t("common.upload") }}</button>
  </form>
</div>
</template>

<script>
import {printObj, readableSize} from 'libs/utils.js'

export default {
  props: {
    storageApi: {
      type: Object
    },
    uploadFile: {
      type: Function
    },
    showProgress: {
      type: Boolean,
      default: false
    },
    minSize: {
      type: Number,
      default: 0
    },
    maxSize: {
      type: Number
    },
    checkFileName: {
      type: Function
    },
    accept: {
      type: String,
      default: ''
    },
    uploadType: {
      type: String,
      default: 'default'
    },
    uploadFileName: {
      type: String
    },
    success: {
      type: Function
    },
    error: {
      type: Function,
      required: true
    }
  },
  data: function() {
    return {
      state: '',
      fileName: '',
      validFile: false,
      progress: 0
    }
  },
  methods: {
    onUploadProgress (e) {
      this.progress = 100 * e.loaded/e.total
    },
    onUploadAbort (e) {
      this.error(this.$t('error.abort'))
    },
    onUploadTimeout (e) {
      this.error(this.$t('error.timeout'))
    },
    doUploadFile (content) {
      this.state = 'uploading'

      let fileName = this.uploadFileName || this.fileName
      if (this.storageApi) {
        this.storageApi.uploadFile(this.uploadType, fileName, content, {
          onprogress: this.onUploadProgress,
          onabort: this.onUploadAbort,
          ontimeout: this.onUploadTimeout
        }).then(function(res) {
          this.success && this.success(res.data)
          this.uploadEnd()
        }.bind(this), function(res) {
          this.error()
          this.uploadEnd()
        }.bind(this))        
      } else {
        this.uploadFile({
          uploadType: this.uploadType,
          fileName: fileName,
          content: content,
          endCb: this.uploadEnd
        })
      }
    },
    onSubmit (e) {
      if (!this.validFile) {
        this.error(this.$t('error.invalidFile'))
        return        
      }

      this.state = 'reading'

      var reader = new FileReader()
      reader.onload = function(e) {
        this.doUploadFile(e.target.result)
      }.bind(this)
      reader.onerror = function(e) {
        this.error(this.$t('error.reading'))
        this.uploadEnd()
      }.bind(this)
      reader.readAsArrayBuffer(this.file)
    },
    isValidFile (file) {
      if (file.size < this.minSize) {
        this.error(this.$t('error.smallFile', {
          size: readableSize(file.size), 
          limit: readableSize(this.minSize)
        }))
        return false        
      }
      if (typeof this.maxSize != 'undefined') {
        if (file.size > this.maxSize) {
          this.error(this.$t('error.largeFile', {
            size: readableSize(file.size), 
            limit: readableSize(this.maxSize)
          }))
          return false
        }
      }

      if (this.checkFileName) {
        if (!this.checkFileName(file.name)) {
          this.error(this.$t('error.unknownFileName'))
          return false
        }
      }

      return true
    },
    onChange () {
      var file = this.$els.container.files[0]

      if (this.isValidFile(file)) {
        this.file = file
        this.fileName = file.name
        this.validFile = true
      } else {
        this.file = null
        this.fileName = ""
        this.validFile = false
      }
    },
    uploadEnd () {
      this.state = ''
      this.file = null
      this.validFile = false
      this.fileName = ''
      this.progress = 0
    }
  }
}
</script>

<style>
.btn-file {
  position: relative;
  overflow: hidden;
}
.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  filter: alpha(opacity=0);
  opacity: 0;
  background: red;
  cursor: inherit;
  display: block;
}
input[readonly] {
  background-color: white !important;
  cursor: text !important;
}
</style>